package com.brk.socket.server.websocket;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.brk.socket.common.CommonResult;
import com.brk.socket.common.ResultCodeEnum;
import com.brk.socket.entity.Location;
import com.brk.socket.entity.LocationDO;
import com.brk.socket.mapper.LocationMapper;
import com.brk.socket.util.LocationInfoUtil;
import com.brk.socket.util.gps.PositionUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Controller
@ServerEndpoint("/dispose")
public class WebSocketDispose {

    private static LocationMapper locationMapper;

    public WebSocketDispose() {
    }

    @Autowired
    public WebSocketDispose(LocationMapper locationMapper) {
        WebSocketDispose.locationMapper = locationMapper;
    }

    //websocket客户端session
    private Session session;

    //使用一个线程安全的集合来存放WebSocket客户端的对象
    private static ConcurrentHashMap<String, WebSocketDispose> webSocketMap = new ConcurrentHashMap<>();


    private static Location setLocation;

    public static void setSetLocation(Location setLocation) {
        WebSocketDispose.setLocation = setLocation;
    }

    /**
     * 连接建立后触发的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        log.info("onOpen:" + session.getId());
        this.session = session;
        webSocketMap.put(session.getId(), this);
    }


    /**
     * 连接关闭触发方法
     */
    @OnClose
    public void onClose() {
        webSocketMap.remove(session.getId());
        log.info("OnClose:" + session.getId());

    }


    /**
     * 接收到客户端消息时触发的方法
     */
    @OnMessage
    public void onMessage(String msg, Session session) throws Exception {
        log.info("收到" + session.getId() + "的消息：" + msg);

        if(msg != null && msg.contains("ping")) {
            return;
        }

        if (msg != null && msg.length() > 0) {
            Location location = JSON.toJavaObject(JSON.parseObject(msg), Location.class);
            if (location != null) {
                if (!LocationInfoUtil.checkLocation(setLocation.getPolyX(), setLocation.getPolyY(), location.getX(), location.getY())) {
                    sendMessageAll(JSON.toJSONString(CommonResult.failed(ResultCodeEnum.ERROR_EXCEPTION, location)));
                } else {
                    sendMessageAll(JSON.toJSONString(CommonResult.success(ResultCodeEnum.SAFE, location)));
                }
            }
        }


    }


    /**
     * 发生异常时触发的方法
     */
    @OnError
    public void onError(Session session, Throwable throwable) {
        log.info(session.getId() + "发生异常：" + throwable.getMessage());
        throwable.printStackTrace();
    }

    /**
     * 发送消息给客户端
     */
    public void sendMessage(String msg, String serverId) throws Exception {

        this.session.getBasicRemote().sendText(msg);
    }

    private void loadLocation(Location location) {
        LocationDO locationDO = locationMapper.selectOne(new QueryWrapper<>());
        log.info("查询出围栏:" + locationDO);
        //没有设置围栏
        if (locationDO == null) {
            sendMessageAll(JSON.toJSONString(CommonResult.failed(ResultCodeEnum.ERROR_POINT_NULL, ResultCodeEnum.ERROR_POINT_NULL.getMessage(), location)));
            return;
        }
        setLocation = new Location();
        LocationInfoUtil.pareLocation(locationDO.getPolyX(), locationDO.getPolyY(), setLocation);

        log.info("解析出围栏" + setLocation.toString());

    }

    /**
     * 发送消息到所有客户端
     */
    public void sendMessageAll(String msg) {
        try {
            for (Map.Entry<String, WebSocketDispose> entry : webSocketMap.entrySet()) {
                entry.getValue().session.getBasicRemote().sendText(msg);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void sendLocation(Location location) {
        if (setLocation == null) {
            loadLocation(location);
            return;
        }
//        log.info("比较前 转换后的数据" + location.toString());
        sendMessageAll(JSON.toJSONString(CommonResult.success(location)));

    }


}
